package ch.unisi.inf.editor;

import ch.unisi.inf.engine.Image;

import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.border.*;



import java.util.List;
import java.util.ArrayList;


/**
 *  
 *  
 * @author  matthias.eberli@lu.unisi.ch
 */
public class ImageEditorFrame extends JFrame
{
    
    // static fields:
    private static JFileChooser fileChooser = new JFileChooser(System.getProperty("/Users"));

    // fields for the GUI
    private ImagePanel imagePanel;

    private JPanel buttonsPanel;

    private JPanel optionsPanel;
    private JComboBox filterComboBox;
    private JComboBox filterComboList;
    private EditorButtonFrame buttonsFrame;
    private JMenu filterMenu;
    private JMenu editMenu;
    private JMenuItem item;
    
    private JMenuBar menuBar;
    
    // fields 
    private final List<Filter> filters;
    private List<ImageInfo> infos;
    private final ArrayList<ImageEditorFrameListener> listeners;
    private Image image;
    
       
    public ImageEditorFrame(final Image image)
    {
    	this.image = image;
        
        filters = createFilters();
        infos = createInfo();
        listeners = new ArrayList<ImageEditorFrameListener>();
        setLayout(new BorderLayout());
       
        setTitle("Image Editor");
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        
        filterMenu = new JMenu("Filters");
        editMenu = new JMenu("Edit");
        menuBar = new JMenuBar();
        
        menuBar.add(filterMenu);
        
        setLayout(new BorderLayout());

        imagePanel = new ImagePanel();
        imagePanel.setImage(image);
       
        imagePanel.setBorder(new EtchedBorder());
        add(imagePanel, BorderLayout.CENTER);
        
        for(final Filter filter : filters) {
            FilterCommand filterCommand = new FilterCommand(imagePanel, filter);
            item = new JMenuItem(filterCommand);
            filterMenu.add(item);
        }

        
        this.setJMenuBar(menuBar);
        
        buttonsFrame = new EditorButtonFrame(image, imagePanel);
        //panel for the buttons like 'save'
        add(buttonsFrame, BorderLayout.SOUTH);
        
        //options and infos of the image displayed on the left
        optionsPanel = new JPanel();
        
        pack();
        setVisible(true);
    }   

    
    public void rotate()
    {
        if(image != null){
            Image tempImage = new Image(image.getPath(), image);
            int width = image.getWidth();
            int height = image.getHeight();
        
            new BufferedImage(height, width, BufferedImage.TYPE_INT_RGB);
            image = new Image(image.getPath(), new BufferedImage(height, width, BufferedImage.TYPE_INT_RGB));
        
            for(int y = 0; y < height; y++) {
                for(int x = 0; x < width; x++) {
                    Color pixel = tempImage.getPixel(x,y);
                    image.setPixel(height-1-y, x, new Color(pixel.getRed(), pixel.getGreen(), pixel.getBlue())); 
                }
            }
            imagePanel.setImage(image);
            pack();
        }
    }       


    
    /**
     * Create and return a list with all the known filters.
     * @return The list of filters.
     */
    public List<Filter> createFilters()
    {
        List<Filter> filterList = new ArrayList<Filter>();
        filterList.add(new DarkerFilter("Darker"));
        filterList.add(new LighterFilter("Lighter"));
        filterList.add(new GrayScaleFilter("Gray Scale"));
        filterList.add(new InvertColorFilter("Invert"));
        filterList.add(new RotateColorsFilter("Switch colors"));
        filterList.add(new MirrorFilter("Mirror"));
        filterList.add(new SmoothFilter("Smooth"));
        filterList.add(new EdgeFilter("Edge"));
        
        return filterList;
    }    
    
    /**
     * creates a list of available info getters
     */
    private List<ImageInfo> createInfo()
    {
        List<ImageInfo> infoList = new ArrayList<ImageInfo>();
        infoList.add(new InfoHue("Hue"));
        infoList.add(new InfoBrightness("Brightness"));
        infoList.add(new InfoSaturation("Saturation"));
        infoList.add(new InfoRed("Red component"));
        infoList.add(new InfoGreen("Green component"));
        infoList.add(new InfoBlue("Blue component"));
        
        return infoList;
    }
    
     //--- listener management
    public void addImageEditorFrameListener(final ImageEditorFrameListener li) {
        listeners.add(li);
    }
    
    public void removeImageEditorFrameListener(final ImageEditorFrameListener li) {
        listeners.remove(li);
    }
    
    private final void fireImageCharged() {
        for (final ImageEditorFrameListener li : listeners) {
            li.imageCharged();
        }
    }

}
